package com.herb.phoenix;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.herb.game.HerbGame;
import com.herb.phoenix.data.HighScore;
import com.herb.phoenix.models.EnemyShip;
import com.herb.phoenix.models.PhoenixShot;
import com.herb.phoenix.models.PhoenixWorld;
import com.herb.phoenix.models.WeaponType;
import com.herb.phoenix.screens.GameScreen;
import com.herb.phoenix.screens.HighScoreScreen;
import com.herb.phoenix.screens.InstructionsScreen;
import com.herb.phoenix.screens.MainMenuScreen;
import com.herb.phoenix.screens.SettingsScreen;
import com.herb.phoenix.screens.ShopScreen;

public class PhoenixGame extends HerbGame
{
	private static final String CAMPAIGN_FILE = "data/phoenixCampaign.json";
	//private static final String CAMPAIGN_FILE = "data/test.json";

	private static final String SETTINGS_FILE = "data/phoenixSettings.json";
	private static final String SAVE_FILE = "phoenixSave.json";
	
	private static final String DEFAULT_USERNAME = "Phoenix";
	
	GameScreen gameScreen;
	MainMenuScreen mainMenuScreen;
	ShopScreen shopScreen;
	HighScoreScreen highScoreScreen;
	InstructionsScreen instructionsScreen;
	SettingsScreen settingsScreen;
	
	PhoenixConfig config;
	
	JSONArray campaign;
	
	private String username;
	
	public Array<HighScore> highScores = new Array<HighScore>();
	private FileHandle saveGameFile;

	
	public PhoenixGame(PhoenixConfig config)
	{
		super();
		this.config = config;
		setUsername(DEFAULT_USERNAME);
	}

	@Override
	protected void initializeLocations()
	{
		fontFntLocation = "fonts/sansserif.fnt";
		fontPngLocation = "fonts/sansserif.png";
		skinLocation = "data/uiskin.json";
		textureAtlasLocation = "images/phoenix.pack";
		skinFonts = new Array<String>();
		skinFonts.add("default-font");
		skinFonts.add("default-font-large");
		skinFonts.add("default-font-small");
	}

	@Override
	protected void initializeScreens()
	{
		FileHandle handle = Gdx.files.internal(CAMPAIGN_FILE);
		try
		{
			JSONObject json = new JSONObject(handle.readString());
			campaign = json.getJSONArray("levels");
		} catch (JSONException e)
		{
			e.printStackTrace();
		}
		
		FileHandle handle2 = Gdx.files.internal(SETTINGS_FILE);
		try
		{
			JSONObject json = new JSONObject(handle2.readString());
			
			EnemyShip.initialize(json.getJSONArray("enemies"));
			PhoenixShot.initialize(json.getJSONArray("phoenixShots"));
			WeaponType.initialize(json.getJSONArray("phoenixWeapons"));
			InstructionsScreen.initialize(json.getJSONArray("instructions"));
		} catch (JSONException e)
		{
			e.printStackTrace();
		}
		
		saveGameFile = Gdx.files.local(SAVE_FILE);
		if(saveGameFile.exists())
		{
			try
			{
				JSONObject json = new JSONObject(saveGameFile.readString());
				
				username = json.getString("username");
				
				JSONArray scores = json.getJSONArray("scores");
				
				for(int i=0;i<scores.length();i++)
				{
					JSONObject scoreObject = scores.getJSONObject(i);
					
					String name = scoreObject.getString("name");
					int level = scoreObject.getInt("level");
					int score = scoreObject.getInt("score");
					
					HighScore highScore = new HighScore(name, level, score);
					
					highScores.add(highScore);
				}
			} catch (JSONException e)
			{
				e.printStackTrace();
			}
		}
		
		mainMenuScreen = new MainMenuScreen(this);
		gameScreen = new GameScreen(this);
		shopScreen = new ShopScreen(this);
		highScoreScreen = new HighScoreScreen(this);
		settingsScreen = new SettingsScreen(this);
		instructionsScreen = new InstructionsScreen(this);
				
		setScreen(mainMenuScreen);
	}
	
	public void startNewGame()
	{
		gameScreen = new GameScreen(this, campaign);
		setScreen(gameScreen);
	}
	
	@Override
	public void log(String s)
	{
		config.log(s);
	}

	public void returnToMainMenu(boolean disposeGame)
	{
		if(disposeGame)
			gameScreen.dispose();
		
		setScreen(mainMenuScreen);
	}
	
	public void goToHighScores()
	{
		setScreen(highScoreScreen);
	}
	
	public void goToInstructions()
	{
		setScreen(instructionsScreen);
	}

	public void goToShop()
	{
		gameScreen.dispose();
		setScreen(shopScreen);
	}
	
	public void bindShopScreen(PhoenixWorld phoenixWorld)
	{
		shopScreen.setWorld(phoenixWorld);
	}

	public void goToNextLevel(PhoenixWorld phoenixWorld)
	{
		gameScreen = new GameScreen(this, phoenixWorld);
		setScreen(gameScreen);
	}

	public void quitGame()
	{
		config.quit();
	}

	public void goToSettings()
	{
		setScreen(settingsScreen);
	}

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}
	
	public void commit()
	{
		JSONObject json = new JSONObject();
		
		try
		{
			json.put("username", username);
			
			JSONArray highScoreJsonArray = new JSONArray();
			
			for(HighScore highScore : highScores)
			{
				JSONObject highScoreJsonObject = new JSONObject();
				
				highScoreJsonObject.put("name", highScore.name);
				highScoreJsonObject.put("level", highScore.level);
				highScoreJsonObject.put("score", highScore.score);
				highScoreJsonArray.put(highScoreJsonObject);
			}
			
			json.put("scores", highScoreJsonArray);
			
		} catch (JSONException e)
		{
			e.printStackTrace();
		}
		
		saveGameFile.writeString(json.toString(), false);
	}
	
	public void saveHighScore(int level, int score)
	{
		int len = highScores.size;
		
		int i = 0;
		
		HighScore newHighScore = new HighScore(username, level, score);
		
		while(i<len && newHighScore.compareTo(highScores.get(i)) < 0)
		{
			i++;
		}
		
		highScores.insert(i, newHighScore);
		
		if(highScores.size > 10)
		{
			highScores.pop();
		}
		
		commit();
	}
}